/* eslint-disable max-lines */
import React, { PureComponent } from 'react';
import { connect } from 'dva';
import { message, Spin } from 'antd';
import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import moment from 'moment';
import { DATA_ENTRY, AdvancedSearch, TableC, ContentPackage, ExportC, NoQueryC, PrimaryC } from '../../../comps';
import { findValueByCode } from '../../../utils/utils';
import config from '../../../comps/business/tradingMarket/config';
import { getUserInfo } from '../../../utils/commonFunc';
import SetColumnsC from './setColumns';
import debounce from 'lodash/debounce'; // 防抖函数
import DataLogs from './DataLogs';
import PropTypes from 'prop-types';
import _ from 'lodash';

@connect(({ positionThroughQueryNewM, globalM, loading }) => ({
  positionThroughQueryNewM,
  globalM,
  loading,
}))
@Form.create()
class PositionThroughQuery extends PureComponent {
  static defaultProps = {
    pageType: undefined, // 1来自主功能， 2时候 来自穿透工作台
    onSearchClick: () => {}, // 点击查询调用透传的组件参数onSearchClick并且抛出产品名称和查询日期
  };

  constructor(props) {
    super(props);
    this.lastFetchId = 0;
    // 绑定lodash的防抖函数，避免频繁搜索的情况
    this.queryTradingCodeList = debounce(this.queryTradingCodeList, 500);
  }

  state = {
    penetrateTableY: 220,
    isShowLog: false, // 数据日志显示隐藏
    columns: undefined,
    dataSource: undefined, //
    currentPage: 1, // 页码
    numInPage: 20, // 每页条数
    currentPageAdujst: 1, // 页码 拆分
    pageInfo: {}, // 后端返回的页码信息
    searchObj: {}, // 查询条件
    isReset: false, // 是否点击重置
    columnsDefault: [
      { title: '产品名称', key: 'productName', display: true, width: 200 },
      { title: '管理方式', key: 'manageType', display: true, width: 100 },
      { title: '底层产品名称', key: 'orginAssetName', display: true, width: 150, type: 'maxContent' },
      { title: '资产类别', key: 'assetClass', display: true, width: 100 },
      { title: '证券代码', key: 'tradingCode', display: true, width: 120, type: 'maxContent' },
      { title: '证券名称', key: 'secuabbr', display: true, width: 120, type: 'maxContent' },
      { title: '交易场所', key: 'exchangeCode', display: true, width: 120 },
      { title: '持仓数量', key: 'holdAmount', type: 'number', toFixed: 2, display: true, width: 150 },
      { title: '市值', key: 'marketValue', type: 'money', display: true, width: 150 },
      { title: '成本价', key: 'costPrice', type: 'money', toFixed: 2, display: true, width: 120 },
      { title: '总成本', key: 'totalCost', type: 'money', toFixed: 2, display: true, width: 150 },
      { title: '到期日', key: 'endDate', type: 'date', display: true, width: 120 },
      { title: '剩余期限（年）', key: 'remaningDay', display: true, width: 140 },
      { title: '发行人', key: 'issuerName', display: true, width: 120, type: 'maxContent' },
      { title: '省份', key: 'province', display: true, width: 100 },
      { title: '主体评级', key: 'comCreditRating', display: true, width: 120 },
      { title: '债项评级', key: 'bndRating', display: true, width: 120 },
      { title: '行业类型', key: 'industryType', display: true, width: 120 },
      { title: '回购方向', key: 'direction', display: false, width: 120 },
      { title: '回购利率(%)', key: 'repoRate', type: 'rate', display: false, width: 120 },
      { title: '交易对手', key: 'counterparty', display: false, width: 120 },
    ],
    tradeDate: undefined, // 最近一次交易日
    isSplit: '1', // 是否穿透
    sortedInfo: null, // 排序对象
    tradingCodeList: [], // 证券代码列表
    positionDimension: 'merge',
    productIds: [], // 产品空数组
  };

  windowChange = () => {
    const searchCardWidth = document.querySelector('#positionQueryNew')?.clientWidth;
    if (searchCardWidth <= 900) {
      this.setState({
        penetrateTableY: 390,
      });
    } else {
      this.setState({
        penetrateTableY: 450,
      });
    }
  };

  // 初始化来自穿透工作台
  initFromPenetrate = () => {
    const columnsCopy = _.cloneDeep(this.state.columnsDefault);
    columnsCopy.map((v) => {
      v.display = false;
      if (['assetClass', 'tradingCode', 'secuabbr', 'exchangeCode', 'holdAmount', 'marketValue', 'costPrice', 'totalCost', 'manageType', 'orginAssetName'].includes(v.key)) {
        v.display = true;
      }
    });
    this.state.columnsDefault = columnsCopy;
    this.queryTradeDate(); // 查询前一个交易日
    const arr = localStorage.getItem(this.props.pageType === 2 ? 'columnsDefaultPenetrate' : 'columnsDefault')
      ? JSON.parse(localStorage.getItem(this.props.pageType === 2 ? 'columnsDefaultPenetrate' : 'columnsDefault'))
      : columnsCopy;
    // 确定表格展示列
    this.colsChange(arr, 'flag');
    // 监听浏览器窗口变化 得到屏幕大小
    window.addEventListener('resize', this.windowChange);
    this.windowChange();
  };

  componentDidMount() {
    // 来自穿透工作台
    if (this.props.pageType === 2) {
      this.initFromPenetrate();
      return;
    }
    const { columnsDefault } = this.state;
    this.queryTradeDate(); // 查询前一个交易日
    const arr = localStorage.getItem(this.props.pageType === 2 ? 'columnsDefaultPenetrate' : 'columnsDefault')
      ? JSON.parse(localStorage.getItem(this.props.pageType === 2 ? 'columnsDefaultPenetrate' : 'columnsDefault'))
      : columnsDefault;
    // 确定表格展示列
    this.colsChange(arr, 'flag');
  }

  // 确定表格展示格式
  colsChange = (arr, type) => {
    const { positionDimension, columnsDefault } = this.state;
    const keys = ['manageType', 'orginAssetName'];
    if (positionDimension == 'noMerge') {
      // 仅当查询条件“持仓维度”为“按是否直投”出现。管理方式、底层产品名称
      arr = type ? arr : columnsDefault;
    } else {
      // 合并
      arr = (type ? arr : columnsDefault).filter((item) => !keys.includes(item.key));
    }
    // 为了列选择得缓存
    if (type) {
      arr.map((item) => {
        columnsDefault.map((x) => {
          if (item.key == x.key) x.display = item.display;
        });
      });
      this.setState({
        columnsDefault: [...columnsDefault],
      });
    }
    this.formatTreeData(arr);
  };

  // 列选择数据调整格式
  formatTreeData = (arr) => {
    const checkedKeys = [];
    // 得到选中项
    arr.map((item) => {
      if (item.display == true) {
        checkedKeys.push(item.key);
      }
    });
    // 处理列选择时 回购有子项的问题
    const temp = [];
    const tree = [];
    arr.map((item) => {
      if (['direction', 'repoRate', 'counterparty'].includes(item.key)) {
        temp.push(item);
      } else {
        tree.push(item);
      }
    });
    tree.push({
      title: '回购',
      key: 'huigou',
      children: temp,
    });
    const treeData = [
      {
        title: '全部',
        key: 'all',
        children: tree,
      },
    ];
    this.setState({
      checkedKeys,
      treeData,
      columns: arr.filter((item) => item.display),
    });
  };

  // 查询前一个交易日
  queryTradeDate = () => {
    this.props.dispatch({
      type: 'positionThroughQueryNewM/queryTradeDate',
      payload: {
        date: moment(new Date()).format('YYYY-MM-DD'),
        tenant: getUserInfo()?.tenantName,
      },
      callback: (data) => {
        if (data) {
          this.AdvancedSearch.props.form.setFieldsValue({
            date: moment(data),
          });
          this.setState(
            {
              tradeDate: moment(data),
            },
            () => {
              if (this.props.pageType === 2) {
                this.onQuery();
              }
            },
          );
        }
      },
    });
  };

  // 查询列表
  queryTableList = () => {
    const {
      globalM: {
        dataDictionary: { FUTURE_CASHFLOW_TYPE = [] },
      },
    } = this.props;
    const { searchObj, isReset, numInPage, currentPage, productIds } = this.state;
    if (isReset) {
      // 判断是否点击了重置 点击页码不进行后台查询
      message.warning('您已重置查询字段，请设置条件后执行查询');
      return;
    }
    const { sortedInfo = {} } = this.state;
    let orderInfo = {};
    if (sortedInfo?.order) {
      orderInfo = {
        orderByField: sortedInfo?.columnKey,
        orderDirection: sortedInfo?.order == 'descend' ? 'DESC' : 'ASC',
      };
    }
    this.setState({
      loading: true,
    });
    if (searchObj?.productIds?.length) {
      searchObj.productIds = productIds;
    }
    const params = {
      ...searchObj,
      date: searchObj.date ? searchObj.date.format('YYYY-MM-DD') : undefined,
      pageInfo: {
        currentPage,
        numInPage,
      },
      isSplit: searchObj.isSplit == '1',
      orderInfo,
    };
    this.props.dispatch({
      type: 'positionThroughQueryNewM/queryTableList',
      payload: {
        ...params,
      },
      callback: (data) => {
        this.setState({
          loading: false,
        });
        if (data) {
          data.dataSource.map((item, key) => {
            item.key = key;
          });
          this.setState({
            // columns: columnsDefault.filter(item => item.display),
            dataSource: data.dataSource ? [...data.dataSource] : [],
            pageInfo: data.pageInfo || {},
          });
        } else {
          this.setState({
            // columns: columnsDefault.filter(item => item.display),
            dataSource: [],
            pageInfo: {},
          });
        }
      },
    });
  };

  // 表格页码排序改变调用
  handleTableChange = (pagination, filter, sorter) => {
    const { current, pageSize } = pagination;
    this.setState(
      {
        currentPage: current,
        numInPage: pageSize,
        sortedInfo: sorter,
      },
      () => {
        this.queryTableList();
      },
    );
  };

  // 表格列表
  renderTable = () => {
    const { currentPage, numInPage, columns, dataSource, pageInfo } = this.state;
    const {
      globalM: {
        dataDictionary: { LIMITATION_ASSET_TYPE = [], REPURCHASE_DIRECTION = [] },
      },
    } = this.props;
    let { sortedInfo } = this.state;
    sortedInfo = sortedInfo || {};
    columns &&
      columns.map((item) => {
        // if (item.key == 'productType' || item.key == 'exchangeCode' || item.key == 'code' || item.key == 'startDate' || item.key == 'endDate') {
        item.sorter = true;
        item.sortOrder = sortedInfo.columnKey === item.key && sortedInfo.order;
        // }
        if (item.key == 'exchangeCode') {
          item.render = (text, record) => {
            if (text) {
              const findvalue = config.filter((item) => {
                return item.value == text;
              });
              if (findvalue && findvalue.length > 0) {
                return findvalue[0].title;
              } else {
                return '--';
              }
            } else {
              return '--';
            }
          };
        }
        if (item.key == 'assetClass') {
          item.render = (text, record) => {
            if (text == undefined || text == null) return '--';
            return findValueByCode(text, LIMITATION_ASSET_TYPE);
          };
        }
        if (item.key == 'direction' || item.key == 'counterparty' || item.key == 'endDate' || item.key == 'repoRate') {
          item.render = (text, record) => {
            if (record.assetClass != 'HG' && !record.endDate) {
              return undefined; // 只有回购展示这三项 或者  后端如果返回了到期日的 也要展示
            } else {
              if (item.key == 'direction') {
                if (text == undefined || text == null) return '--';
                else return findValueByCode(text, REPURCHASE_DIRECTION);
              }
              if (item.key == 'repoRate') {
                if (text == undefined || text == null) return '--';
                else return Number(text).toFixed(2);
              } else if (text == undefined || text == null) return '--';
              else {
                if (item.key == 'endDate') return moment(text).format('YYYY-MM-DD');
                return text;
              }
            }
          };
        }
      });
    return (
      <div>
        <TableC
          rowKey='key'
          scroll={{ x: 'max-content' }}
          onChange={this.handleTableChange}
          current={currentPage}
          total={pageInfo.total || 0}
          pageSize={numInPage}
          columns={columns}
          dataSource={dataSource}
          loading={this.state.loading}
          selfScrollY={true}
        />
      </div>
    );
  };

  // 渲染穿透工作台的列表
  renderPenetrateTable = () => {
    const { currentPage, numInPage, columns, dataSource, pageInfo, penetrateTableY } = this.state;
    const {
      globalM: {
        dataDictionary: { LIMITATION_ASSET_TYPE = [], REPURCHASE_DIRECTION = [] },
      },
      pageType,
    } = this.props;
    let { sortedInfo } = this.state;
    sortedInfo = sortedInfo || {};
    columns &&
      columns.map((item) => {
        // if (item.key == 'productType' || item.key == 'exchangeCode' || item.key == 'code' || item.key == 'startDate' || item.key == 'endDate') {
        item.sorter = true;
        item.sortOrder = sortedInfo.columnKey === item.key && sortedInfo.order;
        // }
        if (item.key == 'exchangeCode') {
          item.render = (text, record) => {
            if (text) {
              const findvalue = config.filter((item) => {
                return item.value == text;
              });
              if (findvalue && findvalue.length > 0) {
                return findvalue[0].title;
              } else {
                return '--';
              }
            } else {
              return '--';
            }
          };
        }
        if (item.key == 'assetClass') {
          item.render = (text, record) => {
            if (text == undefined || text == null) return '--';
            return findValueByCode(text, LIMITATION_ASSET_TYPE);
          };
        }
        if (item.key == 'direction' || item.key == 'counterparty' || item.key == 'endDate' || item.key == 'repoRate') {
          item.render = (text, record) => {
            if (record.assetClass != 'HG' && !record.endDate) {
              return undefined; // 只有回购展示这三项 或者  后端如果返回了到期日的 也要展示
            } else {
              if (item.key == 'direction') {
                if (text == undefined || text == null) return '--';
                else return findValueByCode(text, REPURCHASE_DIRECTION);
              }
              if (item.key == 'repoRate') {
                if (text == undefined || text == null) return '--';
                else return Number(text).toFixed(2);
              } else if (text == undefined || text == null) return '--';
              else {
                if (item.key == 'endDate') return moment(text).format('YYYY-MM-DD');
                return text;
              }
            }
          };
        }
      });

    return (
      <div>
        <TableC
          rowKey='key'
          scroll={{ x: 'max-content', y: this.props.showOnly ? 220 : penetrateTableY }}
          onChange={this.handleTableChange}
          current={currentPage}
          total={pageInfo.total || 0}
          size={'small'}
          pageSize={numInPage}
          columns={columns}
          dataSource={dataSource}
          loading={this.state.loading}
          selfScrollY={true}
        />
      </div>
    );
  };

  // 是否穿透变化
  changeSplit = (e) => {
    this.setState(
      {
        isSplit: e,
        positionDimension: 'merge',
        tradingCodeList: [], // 清空证券代码
      },
      () => {
        this.AdvancedSearch.props.form.setFieldsValue({
          tradingCodes: undefined,
        });
      },
    );
  };

  // 获取导出入参
  getParams = () => {
    const { searchObj, productIds } = this.state;
    const params = {
      ...searchObj,
      date: searchObj.date ? searchObj.date.format('YYYY-MM-DD') : undefined,
      isSplit: searchObj.isSplit == '1',
      tradingCodes: searchObj.tradingCodes ? searchObj.tradingCodes?.join(',') : null,
      productIds: searchObj.productIds ? productIds?.join(',') : null,
    };
    return params;
  };

  // 列变化
  changeCols = (cols, checkedKeys) => {
    this.setState({
      columnsDefault: [...cols],
      columns: cols.filter((item) => item.display),
      checkedKeys: [...checkedKeys],
    });
  };

  // 模糊查询证券代码
  queryTradingCodeList = (e) => {
    const obj = this.AdvancedSearch?.props?.form?.getFieldsValue();
    if (obj.date != undefined && obj.isSplit != undefined) {
      // 前两个选项必填 才可以搜索
      if (e == '') {
        // 如果无数据 则不请求，必填项
        this.setState({
          tradingCodeList: [],
        });
        return;
      }
      this.lastFetchId += 1;
      const fetchId = this.lastFetchId;
      this.setState({
        tradingCodeList: [],
        queryLoading: true,
      });
      this.props.dispatch({
        type: 'positionThroughQueryNewM/queryTradingCodeList',
        payload: {
          securityCodeOrName: e,
          date: moment(obj.date).format('YYYY-MM-DD'),
          isSplit: obj.isSplit == '1',
          fetchId,
          positionDimension: this.state.positionDimension,
          productIds: obj.productIds ? this.state.productIds : undefined, // 增加产品id入参
        },
        callback: (data, currentId) => {
          this.setState({
            queryLoading: false,
          });
          if (currentId !== this.lastFetchId) {
            // 判断是请求的数据是否是本次数据
            return;
          }

          this.setState({
            tradingCodeList: data || [],
          });
        },
      });
    } else {
      message.warning('截止日期和是否穿透必填');
    }
  };

  componentWillUnmount() {
    localStorage.setItem(this.props.pageType === 2 ? 'columnsDefaultPenetrate' : 'columnsDefault', JSON.stringify(this.state.columnsDefault));
  }

  // 持仓维度变化 保存变量
  onChangeDimension = (e) => {
    this.setState(
      {
        positionDimension: e,
        tradingCodeList: [], // 清空证券代码
      },
      () => {
        this.AdvancedSearch.props.form.setFieldsValue({
          tradingCodes: undefined,
        });
      },
    );
  };

  // 选中产品
  productOnChange = (e) => {
    this.setState({
      tradingCodeList: [], // 清空证券代码
    });
    this.AdvancedSearch.props.form.setFieldsValue({
      tradingCodes: undefined,
    });
    // 取产品的code 传给后台
    if (!e) {
      this.setState({
        productIds: [],
      });
      return;
    }
    const arr = e.info.map((item) => {
      return item.portfolioCode;
    });
    this.setState({
      productIds: arr || [],
    });
  };

  showLog = (isShowLog) => {
    this.setState({ isShowLog });
  };

  onQuery = (e) => {
    if (!this.flag) this.flag = true; // 判断当前是否点击过查询按钮
    if (e) {
      if (!e.date) {
        return;
      }
    }
    this.colsChange([]); // 确定columns

    const fieldsValue = this.AdvancedSearch.props.form.getFieldsValue();
    // 如果来自穿透工作台抛出日期和产品id
    if (this.props.pageType === 2) {
      this.props.onSearchClick({
        date: fieldsValue.date,
        productIds: fieldsValue.productIds,
      });
    }
    this.setState(
      {
        searchObj:
          {
            ...e,
            ...fieldsValue,
          } || {},
        currentPage: 1,
        isReset: false,
      },
      () => {
        this.queryTableList(); // 点击查询按钮
      },
    );
  };

  render() {
    const { treeData, isSplit, checkedKeys, columnsDefault, isShowLog } = this.state;
    const positionDimensionList = [
      { value: 'merge', title: '合并' },
      { value: 'noMerge', title: '是否直投' },
    ];
    const searchProps = {
      dataSource: [
        {
          dataIndex: 'date',
          title: this.props.pageType === 2 ? '查询日期' : '截止日期',
          type: DATA_ENTRY.SINGLEDATE,
          // formItemLayout:FormItemLayout,
          disableEnd: this.state.tradeDate ? moment(this.state.tradeDate).add(1, 'days') : undefined,
          allowClear: false,
          rules: [{ required: true, message: '截止日期必填' }],
        },
        {
          dataIndex: 'isSplit',
          title: '是否穿透',
          type: DATA_ENTRY.SELECT,
          isTrueFalseJudge: true,
          initialValue: '1',
          onChange: this.changeSplit,
          rules: [{ required: true, message: '是否穿透必填' }],
        },
        {
          dataIndex: 'positionDimension',
          title: '持仓维度',
          type: DATA_ENTRY.SELECT,
          dataSource: positionDimensionList,
          initialValue: 'merge',
          hide: isSplit == '0',
          rules: [{ required: true }],
          onChange: this.onChangeDimension,
        },
        {
          dataIndex: 'productIds',
          title: this.props.pageType === 2 ? '产品名称' : '产品',
          type: DATA_ENTRY.PRODUCTLIST,
          multiple: true,
          onChange: this.productOnChange,
        },
        {
          dataIndex: 'tradingCodes',
          title: this.props.pageType === 2 ? '证券名称' : '证券代码',
          type: DATA_ENTRY.SELECT,
          placeholder: '请输入证券代码或者名称',
          allowClear: true,
          dataSource: this.state.tradingCodeList || [],
          notFoundContent: this.state.queryLoading ? <Spin size='small' /> : null,
          isMultiple: true,
          filterOption: false,
          onSearch: this.queryTradingCodeList,
        },
      ],
      onQuery: (e) => {
        this.onQuery(e);
      },
      onClear: () => {
        // 点击重置按钮
        this.setState({
          searchObj: { date: this.state.tradeDate }, // 查询条件
          isReset: true,
          isSplit: '1',
          sortedInfo: null, // 排序对象
          positionDimension: 'merge',
          tradingCodeList: [],
        });
        this.AdvancedSearch.props.form.setFieldsValue({ date: this.state.tradeDate, tradingCodes: undefined });
      },
      onRef: (ref) => {
        this.AdvancedSearch = ref;
      },
    };
    const deadline = this.AdvancedSearch?.props.form.getFieldValue('date');
    const { pageType } = this.props;
    return (
      <div>
        {this.props.pageType === 2 ? (
          <div>
            <div>
              <AdvancedSearch {...searchProps} parentId={pageType === 2 ? 'positionQueryNew' : undefined} />
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <div
                style={{
                  width: 'calc(100% - 285px)',
                  background: 'rgba(35, 102, 255, 0.0500)',
                  color: '#497AFF',
                  height: 32,
                  paddingLeft: 16,
                  marginTop: 4,
                  lineHeight: '32px',
                }}
              >
                每日下午6点后可查询前一交易日穿透结果。
              </div>
              <div style={{ marginBottom: '16px', marginTop: '20px', display: 'flex', justifyContent: 'end' }}>
                <PrimaryC style={{ marginRight: '10px' }} title='数据日志' disabled={!(this.state.dataSource && this.state.dataSource?.length)} onClick={this.showLog} />
                <div style={{ marginRight: '10px' }}>
                  <ExportC
                    url={'gateway/risk-holding/risk/holding/web/positionInfo/export'}
                    search={this.getParams()}
                    disabled={!(this.state.dataSource && this.state.dataSource?.length)}
                  />
                </div>
                <SetColumnsC columns={columnsDefault} checkedKeys={checkedKeys} treeData={treeData} changeCols={this.changeCols} disabled={!this.state.columns?.length} />
              </div>
            </div>
            {isShowLog ? <DataLogs showLog={this.showLog} deadline={deadline} /> : null}
            {this.flag ? (
              this.renderPenetrateTable()
            ) : (
              <div style={{ marginTop: '10px' }}>
                <NoQueryC />
              </div>
            )}
          </div>
        ) : (
          <ContentPackage
            title='穿透持仓查询'
            contentHtml={
              <div>
                <div>
                  <AdvancedSearch {...searchProps} />
                </div>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <div />
                  {/* <PrimaryC style={{ marginRight: '10px' }} title='数据日志' disabled={!(this.state.dataSource && this.state.dataSource?.length)} onClick={this.showLog} /> */}
                  <div style={{ marginBottom: '16px', marginTop: '20px', display: 'flex', justifyContent: 'end' }}>
                    <div style={{ marginRight: '10px' }}>
                      <ExportC
                        url={'gateway/risk-holding/risk/holding/web/positionInfo/export'}
                        search={this.getParams()}
                        disabled={!(this.state.dataSource && this.state.dataSource?.length)}
                      />
                    </div>
                    <SetColumnsC columns={columnsDefault} checkedKeys={checkedKeys} treeData={treeData} changeCols={this.changeCols} disabled={!this.state.columns?.length} />
                  </div>
                </div>
                {isShowLog ? <DataLogs showLog={this.showLog} deadline={deadline} /> : null}
                {this.flag ? (
                  this.renderTable()
                ) : (
                  <div style={{ marginTop: '10px' }}>
                    <NoQueryC />
                  </div>
                )}
              </div>
            }
          />
        )}
      </div>
    );
  }
}
PositionThroughQuery.propTypes = {
  pageType: PropTypes.number,
  onSearchClick: PropTypes.func,
};
export default PositionThroughQuery;
